import { MessageBox } from "element-ui";
import moment from "moment";

/**
 * Parse the time to string
 * @param {(Object|string|number)} time
 * @param {string} cFormat
 * @returns {string | null}
 */
export function parseTime(time, cFormat) {
    if (arguments.length === 0 || !time) {
        return null;
    }
    const format = cFormat || "{y}-{m}-{d} {h}:{i}:{s}";
    let date;
    if (typeof time === "object") {
        date = time;
    } else {
        if (typeof time === "string") {
            if (/^[0-9]+$/.test(time)) {
                // support "1548221490638"
                time = parseInt(time);
            } else {
                // support safari
                // https://stackoverflow.com/questions/4310953/invalid-date-in-safari
                time = time.replace(new RegExp(/-/gm), "/");
            }
        }

        if (typeof time === "number" && time.toString().length === 10) {
            time = time * 1000;
        }
        date = new Date(time);
    }
    const formatObj = {
        y: date.getFullYear(),
        m: date.getMonth() + 1,
        d: date.getDate(),
        h: date.getHours(),
        i: date.getMinutes(),
        s: date.getSeconds(),
        a: date.getDay()
    };
    const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => {
        const value = formatObj[key];
        // Note: getDay() returns 0 on Sunday
        if (key === "a") {
            return ["日", "一", "二", "三", "四", "五", "六"][value];
        }
        return value.toString().padStart(2, "0");
    });
    return time_str;
}

/**
 * @param {string} url
 * @returns {Object}
 */
export function param2Obj(url) {
    const search = decodeURIComponent(url.split("?")[1]).replace(/\+/g, " ");
    if (!search) {
        return {};
    }
    const obj = {};
    const searchArr = search.split("&");
    searchArr.forEach(v => {
        const index = v.indexOf("=");
        if (index !== -1) {
            const name = v.substring(0, index);
            const val = v.substring(index + 1, v.length);
            obj[name] = val;
        }
    });
    return obj;
}

/**
 * @param {Function} func
 * @param {number} wait
 * @param {boolean} immediate
 * @return {*}
 */
export function debounce(func, wait, immediate) {
    let timeout, args, context, timestamp, result;

    const later = function () {
        // 据上一次触发时间间隔
        const last = +new Date() - timestamp;

        // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
        if (last < wait && last > 0) {
            timeout = setTimeout(later, wait - last);
        } else {
            timeout = null;
            // 如果设定为immediate===true，因为开始边界已经调用过了此处无需调用
            if (!immediate) {
                result = func.apply(context, args);
                if (!timeout) context = args = null;
            }
        }
    };

    return function (...args) {
        context = this;
        timestamp = +new Date();
        const callNow = immediate && !timeout;
        // 如果延时不存在，重新设定延时
        if (!timeout) timeout = setTimeout(later, wait);
        if (callNow) {
            result = func.apply(context, args);
            context = args = null;
        }

        return result;
    };
}

export const _toString = Object.prototype.toString;

export const conver = limit => {
    limit = limit - 0;
    if (isNaN(limit)) return limit;
    let size = "";
    if (limit < 0.1 * 1024) {
        //如果小于0.1KB转化成B
        size = limit.toFixed(2) + "B";
    } else if (limit < 0.1 * 1024 * 1024) {
        //如果小于0.1MB转化成KB
        size = (limit / 1024).toFixed(2) + "KB";
    } else if (limit < 0.1 * 1024 * 1024 * 1024) {
        //如果小于0.1GB转化成MB
        size = (limit / (1024 * 1024)).toFixed(2) + "MB";
    } else if (limit < 0.1 * 1024 * 1024 * 1024 * 1024) {
        size = (limit / (1024 * 1024 * 1024)).toFixed(2) + "GB";
    } else if (limit < 0.1 * 1024 * 1024 * 1024 * 1024 * 1024) {
        size = (limit / (1024 * 1024 * 1024 * 1024)).toFixed(2) + "TB";
    } else {
        //其他转化成GB
        size = (limit / (1024 * 1024 * 1024 * 1024 * 1024)).toFixed(2) + "EB";
    }

    const sizestr = size + "";
    // var len = sizestr.indexOf(".");
    // var dec = sizestr.substr(len + 1, 2);
    // if (dec == "00") {
    //   //当小数点后为00时 去掉小数部分
    //   return sizestr.substring(0, len) + sizestr.substr(len + 3, 2);
    // }
    return sizestr;
};

export const blobDownLoad = (blob, fileName) => {
    const $blob = new Blob([blob]);
    const dom = document.createElement("a");
    const href = window.URL.createObjectURL($blob);
    dom.href = href;
    dom.download = fileName;
    dom.click();
    window.URL.revokeObjectURL(href);
};

export const urlDownLoad = (url, title) => {
    const dom = document.createElement("a");
    dom.href = url;
    dom.setAttribute("download", title || "");
    // dom.target = "_black";
    dom.click();
};
const getImageDataURL = image => {
    // 创建画布
    const canvas = document.createElement("canvas");
    canvas.width = image.width;
    canvas.height = image.height;
    const ctx = canvas.getContext("2d");
    // 以图片为背景剪裁画布
    ctx.drawImage(image, 0, 0, image.width, image.height);
    // 获取图片后缀名
    const extension = image.src.substring(image.src.lastIndexOf(".") + 1).toLowerCase();
    // 某些图片 url 可能没有后缀名，默认是 png
    return canvas.toDataURL("image/" + extension, 1);
};

export const downLoadUrl = (downloadName, url) => {
    const tag = document.createElement("a");
    // 此属性的值就是下载时图片的名称，注意，名称中不能有半角点，否则下载时后缀名会错误
    tag.setAttribute("download", downloadName.replace(/\./g, "。"));

    const image = new Image();
    // 设置 image 的 url, 添加时间戳，防止浏览器缓存图片
    image.src = url + "?time=" + new Date().getTime();
    //重要，设置 crossOrigin 属性，否则图片跨域会报错
    image.setAttribute("crossOrigin", "Anonymous");
    // 图片未加载完成时操作会报错
    image.onload = () => {
        tag.href = getImageDataURL(image);
        tag.click();
    };
};

export const mapHandle = source => {
    return source.map(({ value, description }) => ({
        value,
        label: description
    }));
};

export const exportList = async (total, promise, fileName) => {
    let res = null;
    if (total - 0 > 50000) {
        await MessageBox.confirm(
            `当前已选择${total}条数据, 仅支持导出50000条数据。超出部分将忽略, 是否确认导出? `,
            "提示"
        );
        res = await promise;
    } else {
        res = await promise;
    }
    if (res) blobDownLoad(res, fileName);
};

export const multipleSpace = (str, needTrim = true) => {
    if (typeof str === "string") {
        const _str = str.replace(/\s+/g, " ");
        return needTrim ? _str.trim() : _str;
    } else if (typeof str === "object") {
        const obj = {};
        Object.keys(str).forEach(item => {
            obj[item] = multipleSpace(str[item]);
        });
        return obj;
    } else {
        return str;
    }
};

export const diffFormat = (start, end) => {
    const duration = moment.duration(new Date(end).getTime() - new Date(start).getTime());

    const map = {
        years: "y",
        months: "M",
        days: "d",
        hours: "h",
        minutes: "m",
        seconds: "s"
    };
    return Object.keys(map).reduce((prev, current) => {
        const i = duration.get(current);
        if (i > 0) {
            return `${prev}${i}${map[current]} `;
        } else {
            return prev;
        }
    }, "");
};

export const formatTime = (time, format = "YYYY-MM-DD HH:mm:ss") => {
    return time === null || time === undefined || time === ""
        ? "-"
        : moment(time).isValid()
        ? moment(time).format(format)
        : "-";
};

export const copyToClipboard = function (copy_str) {
    //创建一个textarea节点
    const textarea = document.createElement("textarea");
    //为textarea节点添加style属性
    textarea.setAttribute("style", "position:fixed;top:0;left:0;opacity:0;z-index:-10;");
    //把要复制的文本添加到textarea节点中
    let text = document.createTextNode(copy_str);
    textarea.appendChild(text);
    //把textarea节点添加到body节点中
    document.body.appendChild(textarea);
    //选中textarea节点的文本内容
    textarea.select();
    console.log("exec copy");
    //执行复制命令
    if (document.execCommand("copy")) {
        console.log("复制成功");
    } else {
        console.log("复制失败");
    }
    //复制完成后从body节点删除textarea节点
    document.body.removeChild(textarea);
};

/**
 * @name  getTableData
 * @param  {Number} page 当前页码，默认1
 * @param  {Number} pageSize 每页最多显示条数，默认10
 * @param  {Array} totalData 总的数据集，默认为空数组
 * @return {Object} {
    data, //当前页展示数据，数组
    page, //当前页码
    pageSize, //每页最多显示条数
    length, //总的数据条数
  }
 **/

export const getTableData = (page = 1, pageSize = 10, totalData = []) => {
    const { length } = totalData;
    const tableData = {
        data: [],
        page,
        pageSize,
        length
    };
    if (pageSize >= length) {
        //pageSize大于等于总数据长度，说明只有1页数据或没有数据
        tableData.data = totalData;
        tableData.page = 1; //直接取第一页
    } else {
        //pageSize小于总数据长度，数据多余1页
        const num = pageSize * (page - 1); //计算当前页（不含）之前的所有数据总条数
        if (num < length) {
            //如果当前页之前所有数据总条数小于（不能等于）总的数据集长度，则说明当前页码没有超出最大页码
            const startIndex = num; //当前页第一条数据在总数据集中的索引
            const endIndex = num + pageSize - 1; //当前页最后一条数据索引
            tableData.data = totalData.filter(
                (_, index) => index >= startIndex && index <= endIndex
            ); //当前页数据条数小于每页最大条数时，也按最大条数范围筛取数据
        } else {
            //当前页码超出最大页码，则计算实际最后一页的page，自动返回最后一页数据
            const size = parseInt(length / pageSize); //取商
            const rest = length % pageSize; //取余数
            if (rest > 0) {
                //余数大于0，说明实际最后一页数据不足pageSize，应该取size+1为最后一条的页码
                tableData.page = size + 1; //当前页码重置，取size+1
                tableData.data = totalData.filter(
                    (_, index) => index >= pageSize * size && index <= length
                );
            } else if (rest === 0) {
                //余数等于0，最后一页数据条数正好是pageSize
                tableData.page = size; //当前页码重置，取size
                tableData.data = totalData.filter(
                    (_, index) => index >= pageSize * (size - 1) && index <= length
                );
            } //注：余数不可能小于0
        }
    }
    return tableData;
};

export const getQueryString = (name) => {
    const urlString = window.location.href
    const url = new URL(urlString)
    return url.searchParams.get(name)
}
